package com.md24housecall.util;

import java.io.File;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.widget.Toast;

import com.androidquery.AQuery;
import com.androidquery.callback.AjaxCallback;
import com.androidquery.callback.AjaxStatus;
import com.md24housecall.activity.R;
import com.md24housecall.manager.CacheManager;
import com.md24housecall.model.CategoryPartner;
import com.md24housecall.model.Partner;
import com.md24housecall.net.UrlBuilder;

public class Utils {
	private static Utils mInstance;
	private DecimalFormat callDuration = new DecimalFormat("00.00");
	private GlobalConstant constant=GlobalConstant.getInstance();
	private int retryCategory=0;
	private int retryPartner=0;
	private OnRequestCategoryListner mListener; 
	private Toast toast;

	public static Utils getInstance() {
		if (mInstance == null)
			mInstance = new Utils();
		return mInstance;
	}

	private String createBodyEmail(Context myContext) {
		Resources res=myContext.getResources();
		String[] contents = { res.getString(R.string.email_first_name),
				res.getString(R.string.email_last_name),
				res.getString(R.string.email_cell_phone),
				res.getString(R.string.email_home_phone),
				res.getString(R.string.email_full_address),
				res.getString(R.string.email_leave_comment) };
		String content="";
		for(String body:contents){
			content+=body+"\n";
		}
		return content.substring(0, content.lastIndexOf("\n"));
	}
	
	public void showMessage(Context myContext,String msg){
		new AlertDialog.Builder(myContext).setMessage(msg).setNegativeButton(myContext.getString(R.string.button_ok), new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.dismiss();
			}
		}).create().show();
	}
	public void sendEmail(Context myContext) {
		try {
			Intent intent = new Intent(Intent.ACTION_SEND);
			intent.setType("message/rfc822");
			intent.putExtra(Intent.EXTRA_EMAIL, new String[] {constant.EMAIL });
			intent.putExtra(Intent.EXTRA_SUBJECT, myContext.getResources().getString(R.string.register_email_subject));
			intent.putExtra(Intent.EXTRA_TEXT, createBodyEmail(myContext));
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			myContext.startActivity(intent);
		} catch (Exception e) {
			Toast.makeText(myContext, "Don't have any email application",Toast.LENGTH_LONG).show();
		}
	}

	public float getDuration(double duration) {
		duration = (duration / 1000) * 0.0166666666666667;
		// Log.d("DucNM", "duration: "+duration);
		return Float.parseFloat(callDuration.format(duration));
	}

	@SuppressLint("SimpleDateFormat")
	public String getCurrentDateFormat(String format){
		Date currentTime = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(currentTime).toString();
	}
	private int calculateInSampleSize(BitmapFactory.Options options,
			int reqWidth, int reqHeight) {
		// Raw height and width of image
		final int height = options.outHeight;
		final int width = options.outWidth;
		int inSampleSize = 1;

		if (height > reqHeight || width > reqWidth) {

			// Calculate ratios of height and width to requested height and
			// width
			final int heightRatio = Math.round((float) height
					/ (float) reqHeight);
			final int widthRatio = Math.round((float) width / (float) reqWidth);

			// Choose the smallest ratio as inSampleSize value, this will
			// guarantee
			// a final image with both dimensions larger than or equal to the
			// requested height and width.
			inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
		}

		return inSampleSize;
	}

	public Bitmap getBitmapFromFile(File f) {
		BitmapFactory.Options options = new BitmapFactory.Options();
	    options.inJustDecodeBounds = true;
	    BitmapFactory.decodeFile(f.getAbsolutePath(), options);
		options.inSampleSize = calculateInSampleSize(options, constant.width, constant.heigth);
		options.inJustDecodeBounds = false;
		try {
			return BitmapFactory.decodeFile(f.getAbsolutePath(),options);
		} catch (Exception e) {
			// TODO: handle exception
			MyLog.d(GlobalConstant.TAG,"expception getBitmapFromFile: "+e.getMessage());
		}
		return null;
	}

	public void call(Context myContext) {
		try {
			Intent callIntent = new Intent(Intent.ACTION_CALL);
			callIntent.setData(Uri.parse("tel:" + constant.PHONENUMBER));
			myContext.startActivity(callIntent);
		} catch (Exception e) {
			Toast.makeText(myContext, "Don't have any call application",Toast.LENGTH_LONG).show();
		}
	}

	public String getEmailAccount(Context myContext){
		try {
			AccountManager manager = AccountManager.get(myContext);
			Account[] accounts = manager
					.getAccountsByType("com.google");
			List<String> possibleEmail = new LinkedList<String>();

			for (Account account : accounts) {
				possibleEmail.add(account.name);
			}
			return possibleEmail.get(0);
		} catch (Exception e) {
			// TODO: handle exception
			MyLog.d(GlobalConstant.TAG, "exception get skype name: "+e.getMessage());
			return "";
		}
	}
	
	public void clearAllData(Context myContext){
		myContext.deleteDatabase(CacheManager.DATABASE_NAME);
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		constant.code="";
		constant.userType=constant.SINGLE_USER;
		prefs.edit().clear().commit();
	}
	
	public void saveCode(Context myContext, String value) {
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		prefs.edit().putString(constant.KEYCODE, value).commit();
	}

	public String getCode(Context myContext) {
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		return prefs.getString(constant.KEYCODE, "");
	}
	
	public int getUserType(Context myContext) {
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		return prefs.getInt(constant.KEYUSERTYPE, 0);
	}

	public void saveUrl(Context myContext, String value) {
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		prefs.edit().putString(constant.KEYURL, value).commit();
	}

	public String getUrl(Context myContext) {
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		return prefs.getString(constant.KEYURL, "");
	}

	public void savePreferenceBoolean(String key,Context myContext, boolean value){
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		prefs.edit().putBoolean(key, value).commit();
	}
	
	public boolean getPreferenceBoolean(String key,Context myContext, boolean value){
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		return prefs.getBoolean(key, value);
	}
	
	public void savePreferenceString(String key,Context myContext, String value){
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		prefs.edit().putString(key, value).commit();
	}
	
	public String getPreferenceString(String key,Context myContext, String value){
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		return prefs.getString(key, value);
	}
	
	public void savePreferenceInt(String key,Context myContext, int value){
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		prefs.edit().putInt(key, value).commit();
	}
	
	public int getPreferenceInt(String key,Context myContext, int value){
		SharedPreferences prefs = myContext.getSharedPreferences(
				myContext.getPackageName(), Context.MODE_PRIVATE);
		return prefs.getInt(key, value);
	}
	
	public void saveCheckAppFirstRun(Context myContext, boolean value) {
		savePreferenceBoolean(constant.KEYFIRSTRUN, myContext, value);
	}

	public boolean getCheckAppFirstRun(Context myContext) {
		return getPreferenceBoolean(constant.KEYFIRSTRUN, myContext,true);
	}
	
	public void parseCategoryJson(String json,CacheManager cacheManager){
		try {
			JSONArray jsonArray=new JSONArray(json);
			int len = jsonArray.length();
			MyLog.d(GlobalConstant.TAG, "len category: "+len);
//			cacheManager.open();
			cacheManager.clearCategoryPartnerData();
			for (int i = 0; i < len; i++) {
				try {
					JSONObject json_data = jsonArray.getJSONObject(i);
					CategoryPartner category=new CategoryPartner();
					category.setId(json_data.getString("id"));
					category.setName(json_data.getString("name"));
					category.setLogoUrl(json_data.getString("logo_url"));
					category.setShortDescription(json_data.getString("short_description"));
					category.setPriority(json_data.getInt("priority"));
					cacheManager.insertCategoryPartner(category);
				}catch (Exception e) {
					// TODO: handle exception
					MyLog.d(GlobalConstant.TAG, "exception parseCategoryJson: "+e.getMessage());
				}
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			MyLog.d(GlobalConstant.TAG, "Json exception parseCategoryJson: "+e.getMessage());
		}
	}
	
	public void getPartnerCategoryFromApi(final AQuery aQuery,final CacheManager cacheManager,final boolean isRetry){
		aQuery.ajax(UrlBuilder.URL_GETCATEGORYPARTNER, JSONArray.class, new AjaxCallback<JSONArray>(){
			@Override
			public void callback(String url, JSONArray jsonArray, AjaxStatus status) {
				// TODO Auto-generated method stub
				try{
					if(isRetry){
						if(jsonArray==null){
							if(retryCategory<3){
								getPartnerCategoryFromApi(aQuery, cacheManager, isRetry);
								retryCategory++;
								return;
							}
						}
						retryPartner=0;
					}
					MyLog.d(GlobalConstant.TAG, "getPartnerCategoryFromApi status: "+status.getCode());
					if(status.getCode()==200){
						if (jsonArray != null) {
							MyLog.d(GlobalConstant.TAG, "getPartnerCategoryFromApi success");
							String json=jsonArray.toString();
							parseCategoryJson(json,cacheManager);
							constant.isRetryRequestCategory=false;
							if(mListener!=null)
								mListener.onRequestComplete();
						}else{
							MyLog.d(GlobalConstant.TAG, "getPartnerCategoryFromApi empty data");
							constant.isRetryRequestCategory=true;
						}
					}else{
						MyLog.d(GlobalConstant.TAG, "getPartnerCategoryFromApi failed");
						constant.isRetryRequestCategory=true;
					}
				}catch (Exception e) {
					// TODO: handle exception
					MyLog.d(GlobalConstant.TAG, "exception getPartnerCategoryFromApi: "+e.getMessage());
				}
			}
		});
	}
	
	public void parsePartnerJson(String json,CacheManager cacheManager){
		try {
			JSONArray jsonArray=new JSONArray(json);
			int len = jsonArray.length();
//			cacheManager.open();
			cacheManager.clearPartnerData();
			for (int i = 0; i < len; i++) {
				try {
					JSONObject json_data = jsonArray.getJSONObject(i);
					Partner partner=new Partner();
					partner.setId(json_data.getString("id"));
					partner.setName(json_data.getString("name"));
					partner.setDescription(json_data.getString("description"));
					partner.setShortDescription(json_data.getString("short_description"));
					partner.setWebsite(json_data.getString("website"));
					partner.setEmail(json_data.getString("email"));
					partner.setPhone(json_data.getString("telephone"));
					partner.setLogo(json_data.getString("logo"));
					partner.setImageUrl(json_data.getString("logo_url"));
					partner.setCategoryId(json_data.getInt("category_id"));
					partner.setPriority(json_data.getInt("priority"));
					partner.setSkypeName(json_data.getString("skype_name"));
					cacheManager.insertPartner(partner);
				}catch (Exception e) {
					// TODO: handle exception
					MyLog.d(GlobalConstant.TAG, "exception parsePartnerJson: "+e.getMessage());
				}
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			MyLog.d(GlobalConstant.TAG, "json exception parsePartnerJson: "+e.getMessage());
			e.printStackTrace();
		}
	}
	
	public void getPartnerFromApi(final AQuery aQuery,final CacheManager cacheManager,final boolean isRetry){
		aQuery.ajax(UrlBuilder.URL_GETPARTNERINFO, JSONArray.class, new AjaxCallback<JSONArray>(){
			@Override
			public void callback(String url, JSONArray jsonArray, AjaxStatus status) {
				try{
					if(isRetry){
						if(jsonArray==null){
							if(retryPartner<3){
								getPartnerFromApi(aQuery, cacheManager, isRetry);
								retryPartner++;
								return;
							}
						}
						retryPartner=0;
					}
					MyLog.d(GlobalConstant.TAG, "getPartnerFromApi status: "+status.getCode());
					if(status.getCode()==200){
						if (jsonArray != null) {
							MyLog.d(GlobalConstant.TAG, "getPartnerFromApi success");
							String json=jsonArray.toString();
							parsePartnerJson(json,cacheManager);
							constant.isRetryRequestPartner=false;
						}else{
							MyLog.d(GlobalConstant.TAG, "getPartnerFromApi empty data");
							constant.isRetryRequestPartner=true;
						}
					}else{
						MyLog.d(GlobalConstant.TAG, "getPartnerFromApi failed");
						constant.isRetryRequestPartner=true;
					}
				}catch (Exception e) {
					// TODO: handle exception
					MyLog.d(GlobalConstant.TAG, "exception getPartnerFromApi: "+e.getMessage());
				}
			}
		});
	}
	
	
	public void checkConnectionStatus(Context context,AjaxStatus status,String errorMsg){
		MyLog.d(GlobalConstant.TAG, "getcode: "+status.getCode());
		if(toast==null)
			toast=Toast.makeText(context,R.string.dlg_call_code_connection_error,Toast.LENGTH_LONG);
		if (status.getCode() == AjaxStatus.NETWORK_ERROR) {
			toast.setText(R.string.dlg_call_code_connection_error);
			if(!toast.getView().isShown())
				toast.show();
		} else {
			toast.setText(errorMsg);
			if(!toast.getView().isShown())
				toast.show();
		}
	}
	public void setOnRequestCommplete(OnRequestCategoryListner listener){
		mListener=listener;
	}
	
	public boolean isNetworkAvailable(Context context) {
	    ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
	    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
	    return activeNetworkInfo != null;
	}
	
	public String getDeviceSerial(){
		return android.os.Build.SERIAL;
	}
	
	public interface OnRequestCategoryListner{
		public void onRequestComplete();
	}
}
